package com.bsoft.gol.editor.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.*;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.CodingErrorAction;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 网络请求
 */

@Component
@Lazy(false)
public class HttpClient {
    //默认超时 5s
    public final static int connectTimeout = 300000;

    private static String tp = "hai";

//    @Value("${invoke_service_type}")
//    private void setInvokeServiceType(String invokeServiceType) {
//        tp = invokeServiceType;
//    }

    private final static Logger logger = LoggerFactory.getLogger(HttpClient.class);

    private static PoolingHttpClientConnectionManager connManager = null;

    private static CloseableHttpClient httpclient = null;

    static {
        try {
            logger.info("调试1");
            SSLContext sslContext = SSLContexts.custom().useTLS().build();
            sslContext.init(null, new TrustManager[]{new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }

                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }
            }}, null);
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create
                    ().register("http", PlainConnectionSocketFactory.INSTANCE).register("https", new
                    SSLConnectionSocketFactory(sslContext)).build();
            logger.info("调试2");
            connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            logger.info("调试3 {} ",httpclient);
            httpclient = HttpClients.custom().setConnectionManager(connManager).build();
            // Create socket configuration
            SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
            connManager.setDefaultSocketConfig(socketConfig);
            // Create message constraints
            MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(200)
                    .setMaxLineLength(2000).build();
            // Create connection configuration
            ConnectionConfig connectionConfig = ConnectionConfig.custom().setMalformedInputAction(CodingErrorAction
                    .IGNORE).setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8)
                    .setMessageConstraints(messageConstraints).build();
            connManager.setDefaultConnectionConfig(connectionConfig);
            connManager.setMaxTotal(200);
            connManager.setDefaultMaxPerRoute(20);
        } catch (KeyManagementException e) {
            logger.error("KeyManagementException", e);
        } catch (NoSuchAlgorithmException e) {
            logger.error("NoSuchAlgorithmException", e);
        }
    }

    public static JSONObject doPost(String url, String serverName, Map<String, String> params) {
        JSONObject res = new JSONObject();
        Date begin = new Date();
        url += serverName;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (entry.getValue() == null) {
                params.put(entry.getKey(), "");
            }
        }
        logger.info("url:{}", serverName);
        logger.info("入参:{}", params);
        HttpPost post = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeout).setConnectTimeout
                (connectTimeout).setConnectionRequestTimeout(connectTimeout).build();
        post.setConfig(requestConfig);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        Set<String> keySet = params.keySet();
        for (String key : keySet) {
            nvps.add(new BasicNameValuePair(key, params.get(key)));
        }

        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(post);
            try {
                HttpEntity entity = response.getEntity();
                try {
                    if (entity != null) {
                        String str = EntityUtils.toString(entity, "UTF-8");
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        try {
                            res = JSONObject.parseObject(str);
                            logger.info("{}返回值json:{}", serverName, res == null ? null : res.toJSONString());
                        } catch (Exception e) {
                            e.printStackTrace();
                            logger.info("返回值:{}", str);
                        }
                        long l = System.currentTimeMillis() - begin.getTime();
                        if (l > 2000L) {
                            logger.info("接口耗时太长记录：,{}ms,{}", l, serverName);
                        }
                        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + serverName + ")耗费时间：" +
                                l + "毫秒——————————");
                    }
                } finally {
                    if (entity != null) {
                        entity.getContent().close();
                    }
                }
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            res.put("code", -4);
            res.put("data", "");
            res.put("message", "连接超时");
//			res.put("mesgg","连接超时");
        } finally {
            post.releaseConnection();
        }
        return res == null ? new JSONObject() : res;
    }

    /**
     * @Description:psot请求入参是json字符串
     * @param: [serverName, jsonParams]
     * @return: com.alibaba.fastjson.JSONObject
     * @author:tongtp
     * @Date: 2018/10/8
     */
    public static JSONObject doPostJSONRequest(String url, JSONObject jsonParams) {
        JSONObject res = new JSONObject();
        Date begin = new Date();
//		String url = Constants.HIS_CLIENT_URL+serverName;
//        jsonParams.put("hospitalCode","1");
		logger.info("url:{}", url);
		logger.info("入参:{}", jsonParams);
        HttpPost post = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeout).setConnectTimeout
                (connectTimeout)
                .setConnectionRequestTimeout(connectTimeout).build();
        post.setConfig(requestConfig);
        StringEntity requestEntity = null;
        try {
            requestEntity = new StringEntity(jsonParams.toJSONString(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        requestEntity.setContentEncoding("UTF-8");
        post.setHeader("Content-type", "application/json");
        post.setHeader("t", "1");
        post.setEntity(requestEntity);
        try {
            CloseableHttpResponse response = httpclient.execute(post);
            int responseStatusCode = response.getStatusLine().getStatusCode();
            try {
                if (responseStatusCode != 200) {
                    logger.info("responseStatusCode:{}", responseStatusCode);
                    res.put("code", responseStatusCode);
                    res.put("message", "his接口返回错误");
                    res.put("data", "");
                    return res;
                }
                HttpEntity entity = response.getEntity();
                try {
                    if (entity != null) {
                        String str = EntityUtils.toString(entity, "UTF-8");
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        try {
                            if(CommonUtils.isNotEmpty(str)){
                                String firstChar = str.substring(0,1);
                                if(firstChar.equals("\"")){
                                    str=str.substring(1,str.length()-1);
                                }
                                res = JSONObject.parseObject(StringEscapeUtils.unescapeJavaScript(str));
                            }
                            logger.info("{}返回值json:{}", url, res == null ? null : res.toJSONString());
                        } catch (Exception e) {
                            logger.info("返回值:{}", str);
                            e.printStackTrace();
                        }
                        long l = System.currentTimeMillis() - begin.getTime();
                        if (l > 2000L) {
                            logger.info("接口耗时太长记录：,{}ms,{}", l, url);
                        }
                        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + url + ")耗费时间：" +
                                l + "毫秒——————————");
                    }
                } finally {
                    if (entity != null) {
                        entity.getContent().close();
                    }
                }
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (ConnectTimeoutException e) {
            res.put("code", -100);
            res.put("data", "");
            res.put("message", "his接口连接超时");
            logger.warn("his接口连接超时");
            return res;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            post.releaseConnection();

        }
        return res == null ? new JSONObject() : res;
    }
    public static String doPostHbi(String hostUrl, String serviceUrl,String urid , String pwd,  JSONObject requestString) {
        String result = "";

        DataOutputStream out = null;

        BufferedReader reader = null;
        HttpURLConnection connection = null;
        try {
            Date start=new Date();
            String  host = hostUrl + "/?";
            StringBuffer sb = new StringBuffer();
            sb.append("clinical.service=" + serviceUrl);
            sb.append("&urid="+urid);
            sb.append("&pwd="+pwd);
            sb.append("&parameter=" + URLEncoder.encode(requestString.toJSONString(),"utf-8"));

//			logger.info("平台组装后的url:{}", host+sb.toString());
            URL postUrl = new URL(hostUrl+"/");
            connection = (HttpURLConnection) postUrl.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;Charset=UTF-8");
            connection.connect();
            out = new DataOutputStream(connection.getOutputStream());
            out.writeBytes(sb.toString());
            out.flush();
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                result += line;
            }
            System.out.println("结果==============" + result);
            Date end=new Date();
            logger.info("-----调用 HIS 详情 -----\n平台组装后的url: "+host+sb.toString()+"\n入参： "+requestString.toString()+"\n出参: "+result+"\n请求HIS耗时 "+(end.getTime()-start.getTime())+" 毫秒");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {

            if (connection != null) {
                connection.disconnect();
            }

            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return result;

    }


    public static JSONObject doMainPost(String url , Object... obj){
        if(obj == null){
            throw new NullPointerException("参数不能为null");
        }
        if("".equals(url) || url == null){
            throw new NullPointerException("url不能为null");
        }
        logger.info("url:{}", url);
        logger.info("入参:{}", JSONObject.toJSONString(obj));

        JSONObject res = null;
        if(Objects.equals(tp , "his")){
            JSONObject data =  (JSONObject)obj[3];
            data.put("hospitalDistId","A73D49255EC8ECD6069839D354A12B79");
            res = doPostJSONRequest(url+obj[0] ,data);
        }else{
            JSONObject dataa =  (JSONObject)obj[3];
            dataa.put("hospitalDistId","A73D49255EC8ECD6069839D354A12B79");
//			String data = JSONObject.toJSONString(dataa);
            String str = doPostHbi(url ,obj[0].toString() , obj[1].toString() , obj[2].toString(), dataa);
            if(CommonUtils.isNotEmpty(str)){
                String firstChar = str.substring(0,1);
                if(firstChar.equals("\"")){
                    str=str.substring(1,str.length()-1);
                }
                res = JSONObject.parseObject(StringEscapeUtils.unescapeJavaScript(str));
            }
        }
        logger.info("出参:{}",res);
        return res == null ? new JSONObject() : res;
    }
    public static String doGet(String url) {
        logger.info("url :" + url);
        String result = "";
        HttpGet get = new HttpGet(url);
        get.addHeader("Content-Type", "text/html;charset=utf-8");
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(500000).build();
        get.setConfig(requestConfig);

        String var7;
        try {
            CloseableHttpResponse httpResponse = httpclient.execute(get);

            try {
                HttpEntity entity = httpResponse.getEntity();

                try {
                    if (entity == null) {
                        return result;
                    }

                    String str = EntityUtils.toString(entity, "UTF-8");
                    logger.info("[HttpUtils Post]response string :" + str);
                    var7 = str;
                } finally {
                    if (entity != null) {
                        entity.getContent().close();
                    }

                }
            } finally {
                if (httpResponse != null) {
                    httpResponse.close();
                }

            }
        } catch (ClientProtocolException var28) {
            var28.printStackTrace();
            result = var28.getMessage().toString();
            return result;
        } catch (IOException var29) {
            var29.printStackTrace();
            result = var29.getMessage().toString();
            return result;
        } finally {
            get.releaseConnection();
        }

        return var7;
    }

    public static String doPost(String url, String json) {
        logger.info("url :" + url + " , param :" + json);
        HttpPost post = new HttpPost(url);
        post.addHeader("Content-Type", "application/json;charset=utf-8");
        StringEntity s;
        try {
            s = new StringEntity(json, "UTF-8");

            post.setEntity(s);

            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeout).setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).build();
            post.setConfig(requestConfig);

            long start = System.currentTimeMillis();
            CloseableHttpResponse response = httpclient.execute(post);
            long end = System.currentTimeMillis();
            logger.info("[HttpUtils Post]take time :" + (end - start) + "ms");
            try {
                HttpEntity entity = response.getEntity();
                try {
                    if (entity != null) {
                        String str = EntityUtils.toString(entity, "UTF-8");
                        logger.info("[HttpUtils Post]response string :" + str);
                        return str;
                    }
                } finally {
                    if (entity != null) {
                        entity.getContent().close();
                    }
                }
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            post.releaseConnection();
        }
        return "";
    }

    /**
     * @Description:psot请求入参是json字符串
     * @param: [serverName, jsonParams]
     * @return: com.alibaba.fastjson.JSONObject
     * @author:tongtp
     * @Date: 2018/10/8
     */
    public static JSONObject doElectronicPostJSONRequest(String url, JSONObject jsonParams) {
        JSONObject res = new JSONObject();
        Date begin = new Date();
//		String url = Constants.HIS_CLIENT_URL+serverName;
//        jsonParams.put("hospitalCode","1");

        logger.info("url:{}", url);
        logger.info("入参:{}", jsonParams);
        HttpPost post = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(connectTimeout).setConnectTimeout
                (connectTimeout)
                .setConnectionRequestTimeout(connectTimeout).build();
        post.setConfig(requestConfig);
        StringEntity requestEntity = null;
        try {
            requestEntity = new StringEntity(jsonParams.toJSONString(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        requestEntity.setContentEncoding("UTF-8");
        post.setHeader("Content-type", "application/json");
        post.setHeader("requestTag", "1");
        post.setHeader("departmentName", "HIS");
        post.setHeader("organizationId", "1");
        post.setEntity(requestEntity);
        try {
            CloseableHttpResponse response = httpclient.execute(post);
            int responseStatusCode = response.getStatusLine().getStatusCode();
            try {
                if (responseStatusCode != 200) {
                    logger.info("responseStatusCode:{}", responseStatusCode);
                    res.put("code", responseStatusCode);
                    res.put("message", "his接口返回错误");
                    res.put("data", "");
                    return res;
                }
                HttpEntity entity = response.getEntity();
                try {
                    if (entity != null) {
                        String str = EntityUtils.toString(entity, "UTF-8");
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        try {
                            if(CommonUtils.isNotEmpty(str)){
                                String firstChar = str.substring(0,1);
                                if(firstChar.equals("\"")){
                                    str=str.substring(1,str.length()-1);
                                }
                                res = JSONObject.parseObject(StringEscapeUtils.unescapeJavaScript(str));
                            }
                            logger.info("{}返回值json:{}", url, res == null ? null : res.toJSONString());
                        } catch (Exception e) {
                            logger.info("返回值:{}", str);
                            e.printStackTrace();
                        }
                        long l = System.currentTimeMillis() - begin.getTime();
                        if (l > 2000L) {
                            logger.info("接口耗时太长记录：,{}ms,{}", l, url);
                        }
                        logger.info("——————————" + simpleDateFormat.format(new Date()) + "(" + url + ")耗费时间：" +
                                l + "毫秒——————————");
                    }
                } finally {
                    if (entity != null) {
                        entity.getContent().close();
                    }
                }
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (ConnectTimeoutException e) {
            res.put("code", -100);
            res.put("data", "");
            res.put("message", "his接口连接超时");
            logger.warn("his接口连接超时");
            return res;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            post.releaseConnection();

        }
        return res == null ? new JSONObject() : res;
    }

    public static void main(String[] args) {
        String service="/register/patientIsMatch";
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("patientSex","1");
        jsonObject.put("patientBirthday","1988-02-05");
        jsonObject.put("cityCode","");
        jsonObject.put("patientMedicalCardType",1);
        jsonObject.put("hospitalDistId","A73D49255EC8ECD6069839D354A12B79");
        jsonObject.put("patientAddress","nullnullnull");
        jsonObject.put("patientMobile","13864886006");
        jsonObject.put("patientName","吕振");
        jsonObject.put("patientIdentityCardNumber","372928198802050059");
        jsonObject.put("provinceCode","");
        jsonObject.put("patientIdentityCardType",1);
        jsonObject.put("patientMedicalCardNumber","03120217");

//		String clinical.service="/register/queryBusCards";
//		JSONObject jsonObject=new JSONObject();
//		jsonObject.put("hospitalCode","12312");
//		jsonObject.put("patientCode","6484618");
//		jsonObject.put("hospitalDistId","A73D49255EC8ECD6069839D354A12B79");

//		String clinical.service="/register/getPhoneAndCards";
//		JSONObject jsonObject=new JSONObject();
//		jsonObject.put("hospitalCode","1");
//		jsonObject.put("patientIdentityCardType","1");
//		jsonObject.put("patientIdentityCardNumber","104");
//		jsonObject.put("patientName","宁海");
//		jsonObject.put("patientSex","1");
//		jsonObject.put("patientBirthday","1992-03-04");
//		jsonObject.put("patientMobile","13646395332");
//		jsonObject.put("patientMedicalCardType","1");
//		jsonObject.put("patientMedicalCardNumber","110101199003078056");
//		jsonObject.put("operationType","2");
//		jsonObject.put("hospitalDistId","A73D49255EC8ECD6069839D354A12B79");

        //平台调用例子  Obj 参数，1：clinical.service 2：urid 3：pwd 4：JSONobject对象
        doMainPost("http://10.80.5.34:9526/hai/HttpEntry" , new Object[]{service,"","",jsonObject});
        //his调用例子  Obj 参数，1：houzui 2：null 3：null 4：JSONobject对象
//		doMainPost("http://www.baidu.com" , new Object[]{"sss","","",object});
    }

}

